using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace CGShaderIntegration
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class HaasBastianDrawableGameComponent : Microsoft.Xna.Framework.DrawableGameComponent, IMatrices
    {
        public Matrix WorldMatrix { get; set; }
        public Matrix ViewMatrix { get; set; }
        public Matrix ProjectionMatrix { get; set; }

        SpriteBatch spriteBatch;

        // Set the 3D model to draw.
        Model myModel = null;
        Effect myEffect;
        //Effect myEffect2;

        // The aspect ratio determines how to scale 3d to 2d projection.
        float aspectRatio;

        // Set the position of the model in world space, and set the rotation.
        Vector3 sonnePosi = Vector3.Zero;
        Vector3 erdePosi = new Vector3(-7, 0, 0);
        Vector3 mondPosi = new Vector3(-2, 0, 0);

        float erdeRotation = 0.0f;
        float mondRotation = 0.0f;

        // Set the position of the camera in world space, for our view matrix.
        Vector3 cameraPosition = new Vector3(0.0f, 50.0f, 150.0f);

        Matrix sonne;
        Matrix erde;
        Matrix mond;

        ContentManager Content;

        public HaasBastianDrawableGameComponent(Game game)
            : base(game)
        {
            // TODO: Construct any child components here
            Game.Components.Add(this);
            this.Content = game.Content;
            this.aspectRatio = game.GraphicsDevice.Viewport.AspectRatio;
        }


        public override void Initialize()
        {
            // TODO: Add your initialization code here
            

            base.Initialize();
        }

        protected override void  LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here

            myModel = Content.Load<Model>("models\\Sphere-I");
            myEffect = Content.Load<Effect>("effects\\HaasBastianSchachbrettShader");
            if (myModel == null)
            {
                Trace.Assert(myModel != null, "No Modell loaded");
            }
            //myEffect2 = Content.Load<Effect>("RenderToTextureShader");

        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }


        public override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Game.Exit();

            // TODO: Add your update logic here

            erdeRotation += 0.02f;
            mondRotation += 0.05f;

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            //GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here

            //SONNE------------------------------------------------------------    

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in myModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = myEffect;
                    sonne = (Matrix.CreateScale(3.0f) * Matrix.CreateTranslation(sonnePosi));
                    myEffect.Parameters["World"].SetValue(sonne * WorldMatrix);
                    myEffect.Parameters["View"].SetValue(ViewMatrix);// * Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up));
                    myEffect.Parameters["Projection"].SetValue(ProjectionMatrix);// * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
                    myEffect.Parameters["streifenanzahl"].SetValue(20);        
                    
                    //myEffect2.Parameters["matViewProjection"].SetValue(Matrix.CreateScale(10.0f) * Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up) * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
                    //myEffect2.Parameters["matProjection"].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
                    //myEffect2.Parameters["matTeapotXForm"].SetValue(sonne);
                    //myEffect2.Parameters["View"].SetValue(Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up));
                    //myEffect2.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
                    //myEffect.Parameters["streifenanzahl"].SetValue(20);
                }
                // Draw the mesh, using the effects set above.
                try
                {
                    mesh.Draw();
                }
                catch (InvalidOperationException)
                { 
                }
            }

            //ERDE--------------------------------------------------------------- 

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in myModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = myEffect;
                    erde = Matrix.CreateScale(1.0f) * Matrix.CreateTranslation(erdePosi) * Matrix.CreateRotationY(erdeRotation);
                    //myEffect.Parameters["matViewProjection"].SetValue(erde * Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up) * Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));

                    myEffect.Parameters["World"].SetValue(erde * WorldMatrix);
                    myEffect.Parameters["View"].SetValue(ViewMatrix);//Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up));
                    myEffect.Parameters["Projection"].SetValue(ProjectionMatrix);//Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));              
                    myEffect.Parameters["streifenanzahl"].SetValue(20);                  
                }
                // Draw the mesh, using the effects set above.
                try
                {
                    mesh.Draw();
                }
                catch (InvalidOperationException)
                {
                }
            }

            //MOND--------------------------------------------------------------          

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in myModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = myEffect;
                    mond = Matrix.CreateScale(0.5f) * Matrix.CreateTranslation(mondPosi) * Matrix.CreateRotationY(mondRotation);
                    myEffect.Parameters["World"].SetValue(mond * ((Matrix.CreateTranslation(erdePosi) * Matrix.CreateRotationY(erdeRotation)) * WorldMatrix));
                    myEffect.Parameters["View"].SetValue(ViewMatrix);//Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up));
                    myEffect.Parameters["Projection"].SetValue(ProjectionMatrix);//Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 1.0f, 10000.0f));
                    myEffect.Parameters["streifenanzahl"].SetValue(20);
                }
                // Draw the mesh, using the effects set above.
                try
                {
                    mesh.Draw();
                }
                catch (InvalidOperationException)
                {
                }
            }

            base.Draw(gameTime);
        }

        public String GetName()
        {
            return ("HaasBastian");
        }
    }
}
